^tools/security/secpol_tool$
^tools/security/xen/.*$
^tools/tests/test_x86_emulator$
+^tools/vnet/Make.local$
+^tools/vnet/build/.*$
^tools/vnet/gc$
^tools/vnet/gc.*/.*$
^tools/vnet/vnet-module/.*\.ko$
^tools/vnet/vnet-module/\..*\.cmd$
^tools/vnet/vnet-module/\.tmp_versions/.*$
^tools/vnet/vnet-module/vnet_module\.mod\..*$
+^tools/vnet/vnetd/vnetd$
^tools/vtpm/tpm_emulator-.*\.tar\.gz$
^tools/vtpm/tpm_emulator/.*$
^tools/vtpm/vtpm/.*$
=item B<-v | --vnetif> I<vnetifname>
Use I<vnetifname> as the name for the vnet device. If this option
-is not specified the default isto name the device vnifN where N
+is not specified the default is to name the device vnifN where N
is the last field of the vnet id as 4 hex characters.
For example vnif0004. Network device names can be at
most 14 characters.
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
-(at your option) any later version.
\ No newline at end of file
+(at your option) any later version.
PIC_OBJS := $(LIB_SRCS:.c=.opic)
CFLAGS += -Werror -fno-strict-aliasing
+CFLAGS += -O3
+#CFLAGS += -g
# Get gcc to generate the dependencies for us.
CFLAGS += -Wp,-MD,.$(@F).d
--------------------------------------------------------------------
*/
-ub4 hash(const ub1 *k, ub4 length, ub4 initval)
+static inline ub4 _hash(const ub1 *k, ub4 length, ub4 initval)
//register ub1 *k; /* the key */
//register ub4 length; /* the length of the key */
//register ub4 initval; /* the previous hash, or an arbitrary value */
/*-------------------------------------------- report the result */
return c;
}
+
+ub4 hash(const ub1 *k, ub4 length, ub4 initval){
+ return _hash(k, length, initval);
+}
+
/*============================================================================*/
/** Get the bucket for a hashcode in a hash table.
* @return 1 if equal, 0 otherwise
*/
inline int HashTable_key_equal(HashTable *table, void *key1, void *key2){
+ if(table->key_size){
+ return memcmp(key1, key2, table->key_size) == 0;
+ }
return (table->key_equal_fn ? table->key_equal_fn(key1, key2) : key1 == key2);
}
* @return hashcode
*/
inline Hashcode HashTable_key_hash(HashTable *table, void *key){
+ if(table->key_size){
+ return _hash(key, table->key_size, 0);
+ }
return (table->key_hash_fn
? table->key_hash_fn(key)
: hash_hvoid(0, &key, sizeof(key)));
int buckets_n;
/** Number of entries in the table. */
int entry_count;
+ unsigned long key_size;
/** Function to free keys and values in entries. */
TableFreeFn *entry_free_fn;
/** Function to hash keys. */
# 59 Temple Place, suite 330, Boston, MA 02111-1307 USA
#============================================================================
-LINUX_SERIES ?=2.6
-KERNEL_MINOR ?=-xen0
+LINUX_SERIES?=2.6
+KERNEL_MINOR=-xen
-LINUX_VERSION ?= $(shell (/bin/ls -ld $(XEN_ROOT)/pristine-linux-$(LINUX_SERIES).* 2>/dev/null) | \
+LINUX_VERSION?=$(shell (/bin/ls -d $(XEN_ROOT)/pristine-linux-$(LINUX_SERIES).* 2>/dev/null) | \
sed -e 's!^.*linux-\(.\+\)!\1!' )
ifeq ($(LINUX_VERSION),)
$(error Kernel source for linux $(LINUX_SERIES) not found)
endif
-KERNEL_VERSION =$(LINUX_VERSION)$(KERNEL_MINOR)
+KERNEL_VERSION=$(LINUX_VERSION)$(KERNEL_MINOR)
-KERNEL_SRC ?= $(XEN_ROOT)/linux-$(KERNEL_VERSION)
+KERNEL_SRC?=$(shell cd $(XEN_ROOT)/linux-$(KERNEL_VERSION) && pwd)
+
+ifeq ($(KERNEL_SRC),)
+$(error Kernel source for kernel $(KERNEL_VERSION) not found)
+endif
# Get the full kernel release version from its makefile, as the source path
# may not have the extraversion, e.g. linux-2.6.12-xen0 may contain release 2.6.12.6-xen0.
-KERNEL_RELEASE = $(shell make -s -C $(KERNEL_SRC) kernelrelease || \
- make -f $(shell pwd)/Makefile.kver -s -C $(KERNEL_SRC) kernelrelease )
+KERNEL_RELEASE=$(shell make -s -C $(KERNEL_SRC) kernelrelease)
-KERNEL_MODULE_DIR = /lib/modules/$(KERNEL_RELEASE)/kernel
+KERNEL_MODULE_DIR=/lib/modules/$$(KERNEL_RELEASE)/kernel
-$(warning KERNEL_SRC $(KERNEL_SRC))
-#$(warning KERNEL_VERSION $(KERNEL_VERSION))
-$(warning KERNEL_RELEASE $(KERNEL_RELEASE))
+$(warning KERNEL_SRC $(KERNEL_SRC))
+$(warning LINUX_VERSION $(LINUX_VERSION))
+$(warning KERNEL_VERSION $(KERNEL_VERSION))
+$(warning KERNEL_RELEASE $(KERNEL_RELEASE))
+$(warning KERNEL_ MODULE_DIR $(KERNEL_MODULE_DIR))
* @param block size to round to a multiple of
* @return rounded value
*/
-static inline int roundup(int n, int block){
+static inline int roundupto(int n, int block){
if(block <= 1) return n;
block--;
return (n + block) & ~block;
// header and IP header.
plaintext_n = skb->len - ETH_HLEN - ip_n;
// Add size of padding fields.
- ciphertext_n = roundup(plaintext_n + ESP_PAD_N, esp->cipher.block_n);
+ ciphertext_n = roundupto(plaintext_n + ESP_PAD_N, esp->cipher.block_n);
if(esp->cipher.pad_n > 0){
- ciphertext_n = roundup(ciphertext_n, esp->cipher.pad_n);
+ ciphertext_n = roundupto(ciphertext_n, esp->cipher.pad_n);
}
extra_n = ciphertext_n - plaintext_n;
iv_n = esp->cipher.iv_n;
// Have to add some padding for alignment even if pad_n is zero.
ESPState *esp = sa->data;
- data_n = roundup(data_n + ESP_PAD_N, esp->cipher.block_n);
+ data_n = roundupto(data_n + ESP_PAD_N, esp->cipher.block_n);
if(esp->cipher.pad_n > 0){
- data_n = roundup(data_n, esp->cipher.pad_n);
+ data_n = roundupto(data_n, esp->cipher.pad_n);
}
data_n += esp->digest.icv_n;
//data_n += esp->cipher.iv_n;
err = -EINVAL;
goto exit;
}
- esp->cipher.key_n = roundup(sa->cipher.bits, 8);
+ esp->cipher.key_n = roundupto(sa->cipher.bits, 8);
// If cipher is null must use ECB because CBC algo does not support blocksize 1.
if(strcmp(sa->cipher.name, "cipher_null")){
cipher_mode = CRYPTO_TFM_MODE_ECB;
err = -ENOMEM;
goto exit;
}
- esp->cipher.block_n = roundup(crypto_tfm_alg_blocksize(esp->cipher.tfm), 4);
+ esp->cipher.block_n = roundupto(crypto_tfm_alg_blocksize(esp->cipher.tfm), 4);
esp->cipher.iv_n = crypto_tfm_alg_ivsize(esp->cipher.tfm);
esp->cipher.pad_n = 0;
if(esp->cipher.iv_n){
dprintf(">\n");
esp->digest.key = sa->digest.key;
- esp->digest.key_n = bits_to_bytes(roundup(sa->digest.bits, 8));
+ esp->digest.key_n = bits_to_bytes(roundupto(sa->digest.bits, 8));
esp->digest.tfm = crypto_alloc_tfm(sa->digest.name, 0);
if(!esp->digest.tfm){
err = -ENOMEM;
}
+static inline int skb_make_headroom(struct sk_buff **pskb, struct sk_buff *skb, int head_n){
+ int err = 0;
+ dprintf("> skb=%p headroom=%d head_n=%d\n", skb, skb_headroom(skb), head_n);
+ if(head_n > skb_headroom(skb) || skb_cloned(skb) || skb_shared(skb)){
+ // Expand header the way GRE does.
+ struct sk_buff *new_skb = skb_realloc_headroom(skb, head_n + 16);
+ if(!new_skb){
+ err = -ENOMEM;
+ goto exit;
+ }
+ kfree_skb(skb);
+ *pskb = new_skb;
+ } else {
+ *pskb = skb;
+ }
+ exit:
+ return err;
+}
+
/** Send a packet via an etherip tunnel.
- * Adds etherip header, new ip header, new ethernet header around
- * ethernet frame.
+ * Adds etherip header and new ip header around ethernet frame.
*
* @param tunnel tunnel
* @param skb packet
if(etherip_in_udp){
head_n += vnet_n + udp_n;
}
- err = skb_make_room(&skb, skb, head_n, 0);
+ err = skb_make_headroom(&skb, skb, head_n);
if(err) goto exit;
// Null the pointer as we are pushing a new IP header.
return Tunnel_create(etherip_tunnel_type, vnet, addr, base, tunnel);
}
+#if defined(__KERNEL__) && defined(CONFIG_BRIDGE_NETFILTER)
+/** We need our own copy of this as it is no longer exported from the bridge module.
+ */
+static inline void _nf_bridge_save_header(struct sk_buff *skb){
+ int header_size = 16;
+
+ // Were using this modified to use h_proto instead of skb->protocol.
+ if(skb->protocol == htons(ETH_P_8021Q)){
+ header_size = 18;
+ }
+ memcpy(skb->nf_bridge->data, skb->data - header_size, header_size);
+}
+#endif
+
/** Do etherip receive processing.
* Strips the etherip header to extract the ethernet frame, sets
* the vnet from the header and re-receives the frame.
skb->dst = NULL;
nf_reset(skb);
#ifdef CONFIG_BRIDGE_NETFILTER
- // Stop the eth header being clobbered by nf_bridge_maybe_copy_header().
- // Were using this modified to use h_proto instead of skb->protocol.
if(skb->nf_bridge){
- nf_bridge_save_header(skb);
+ // Stop the eth header being clobbered by nf_bridge_maybe_copy_header().
+ _nf_bridge_save_header(skb);
}
#endif
#endif // __KERNEL__
#define tunnel_write_lock(flags) write_lock_irqsave(&tunnel_table_lock, (flags))
#define tunnel_write_unlock(flags) write_unlock_irqrestore(&tunnel_table_lock, (flags))
+void Tunnel_free(Tunnel *tunnel){
+ tunnel->type->close(tunnel);
+ Tunnel_decref(tunnel->base);
+ kfree(tunnel);
+}
+
void Tunnel_print(Tunnel *tunnel){
if(tunnel){
iprintf("Tunnel<%p base=%p ref=%02d type=%s>\n",
goto exit;
}
tunnel_table->entry_free_fn = tunnel_table_entry_free_fn;
+ tunnel_table->key_size = sizeof(TunnelKey);
tunnel_table->key_hash_fn = tunnel_table_key_hash_fn;
tunnel_table->key_equal_fn = tunnel_table_key_equal_fn;
exit:
struct Tunnel *base;
} Tunnel;
+extern void Tunnel_free(struct Tunnel *tunnel);
+
/** Decrement the reference count, freeing if zero.
*
* @param tunnel tunnel (may be null)
static inline void Tunnel_decref(struct Tunnel *tunnel){
if(!tunnel) return;
if(atomic_dec_and_test(&tunnel->refcount)){
- tunnel->type->close(tunnel);
- Tunnel_decref(tunnel->base);
- kfree(tunnel);
+ Tunnel_free(tunnel);
}
}
*
* @param tunnel tunnel (may be null)
*/
-static inline void Tunnel_incref(Tunnel *tunnel){
+static inline void Tunnel_incref(struct Tunnel *tunnel){
if(!tunnel) return;
atomic_inc(&tunnel->refcount);
}
if(!vtable) goto exit;
vtable->table = HashTable_new(VARP_TABLE_BUCKETS);
if(!vtable->table) goto exit;
+ vtable->table->key_size = sizeof(VarpKey);
vtable->table->key_equal_fn = varp_key_equal_fn;
vtable->table->key_hash_fn = varp_key_hash_fn;
vtable->table->entry_free_fn = varp_entry_free_fn;
dprintf("<\n");
}
+#ifdef MODULE_PARM
MODULE_PARM(varp_mcaddr, "s");
-MODULE_PARM_DESC(varp_mcaddr, "VARP multicast address");
-
MODULE_PARM(varp_device, "s");
+#else
+module_param(varp_mcaddr, charp, 0644);
+module_param(varp_device, charp, 0644);
+#endif
+MODULE_PARM_DESC(varp_mcaddr, "VARP multicast address");
MODULE_PARM_DESC(varp_device, "VARP network device");
/*
- * Copyright (C) 2004, 2005 Mike Wray <mike.wray@hp.com>
+ * Copyright (C) 2004, 2005, 2006 Mike Wray <mike.wray@hp.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by the
/* Get macros needed to define system calls as functions in the kernel. */
#define __KERNEL_SYSCALLS__
-static int errno;
+int errno=0;
#include <linux/unistd.h>
#define MODULE_NAME "VARP"
/* Replicate the user-space socket API.
* The parts we need anyway.
+ *
+ * Some architectures use socketcall() to multiplex the socket-related calls,
+ * but others define individual syscalls instead.
+ * Architectures using socketcall() define __ARCH_WANT_SYS_SOCKETCALL.
*/
+#ifdef __ARCH_WANT_SYS_SOCKETCALL
+
/* Define the socketcall() syscall.
* Multiplexes all the socket-related calls.
*
return socketcall(SYS_GETSOCKNAME, args);
}
+#else /* !__ARCH_WANT_SYS_SOCKETCALL */
+
+/* No socketcall - define the individual syscalls. */
+
+static inline _syscall3(int, socket,
+ int, family,
+ int, type,
+ int, protocol);
+
+static inline _syscall3(int, bind,
+ int, fd,
+ struct sockaddr *, umyaddr,
+ int, addrlen);
+
+static inline _syscall3(int, connect,
+ int, fd,
+ struct sockaddr *, uservaddr,
+ int, addrlen);
+
+static inline _syscall6(int, sendto,
+ int, fd,
+ void *, buff,
+ size_t, len,
+ unsigned, flags,
+ struct sockaddr *, addr,
+ int, addr_len);
+
+static inline _syscall6(int, recvfrom,
+ int, fd,
+ void *, ubuf,
+ size_t, size,
+ unsigned, flags,
+ struct sockaddr *, addr,
+ int *, addr_len);
+
+static inline _syscall5(int, setsockopt,
+ int, fd,
+ int, level,
+ int, optname,
+ void *, optval,
+ int, optlen);
+
+static inline _syscall5(int, getsockopt,
+ int, fd,
+ int, level,
+ int, optname,
+ void *, optval,
+ int *, optlen);
+
+static inline _syscall2(int, shutdown,
+ int, fd,
+ int, how);
+
+static inline _syscall3(int, getsockname,
+ int, fd,
+ struct sockaddr *, usockaddr,
+ int *, usockaddr_len);
+
+#endif /* __ARCH_WANT_SYS_SOCKETCALL */
+
/*============================================================================*/
/** Socket flags. */
enum VsockFlag {
* an error.
*/
static int handle_varp_skb(struct sk_buff *skb){
- static int count = 0;
int err = 0;
- count++;
switch(skb->pkt_type){
case PACKET_BROADCAST:
case PACKET_MULTICAST:
goto exit;
}
vif_table->entry_free_fn = vif_entry_free_fn;
+ vif_table->key_size = sizeof(VifKey);
vif_table->key_hash_fn = vif_key_hash_fn;
vif_table->key_equal_fn = vif_key_equal_fn;
err = -ENOMEM;
goto exit;
}
+ vnet_table->key_size = sizeof(VnetId);
vnet_table->key_equal_fn = vnet_key_equal_fn;
vnet_table->key_hash_fn = vnet_key_hash_fn;
vnet_table->entry_free_fn = vnet_entry_free_fn;
ip_send_check(skb->nh.iph);
- if(1){
+#if 1
// Output to skb destination. Will use ip_output(), which fragments.
// Slightly slower than neigh_compat_output() (marginal - 1%).
err = dst_output(skb);
- } else {
+#else
// Sends direct to device via dev_queue_xmit(). No fragmentation?
err = neigh_compat_output(skb);
- }
+#endif
#if 0
if(needs_frags){
err = ip_finish_output(skb);
}
#endif
+
exit:
dprintf("< err=%d\n", err);
return err;
module_exit(vnet_module_exit);
MODULE_LICENSE("GPL");
+#ifdef MODULE_PARM
MODULE_PARM(vnet_encaps, "s");
+#else
+module_param(vnet_encaps, charp, 0644);
+#endif
+
MODULE_PARM_DESC(vnet_encaps, "Vnet encapsulation: etherip or udp.");
#endif
#undef DEBUG
#include "debug.h"
-#ifndef CONFIG_BRIDGE
-#warning Should configure ethernet bridging in kernel Network Options
+#if !defined(CONFIG_BRIDGE) && !defined(CONFIG_BRIDGE_MODULE)
+#warning Should configure Ethernet Bridging in kernel Network Options
+#endif
+
+#ifndef CONFIG_BRIDGE_NETFILTER
+#warning Should configure CONFIG_BRIDGE_NETFILTER in kernel
#endif
static void vnet_dev_destructor(struct net_device *dev){
return err;
}
-static inline int roundup(int n, int k){
+static inline int roundupto(int n, int k){
return k * ((n + k - 1) / k);
}
vnet->header_n += sizeof(struct VnetMsgHdr);
vnet->header_n += sizeof(struct udphdr);
}
- vnet->header_n = roundup(vnet->header_n, 4);
+ vnet->header_n = roundupto(vnet->header_n, 4);
dev = alloc_netdev(0, vnet->device, vnet_dev_init);
if(!dev){
err = -ENOMEM;
if(err) goto exit;
child_string(exp, ovnetif, &device);
if(!device){
- snprintf(dev, IFNAMSIZ-1, "vnif%04x", ntohs(vnet.u.vnet16[7]));
+ snprintf(dev, IFNAMSIZ-1, "vnif%04x", ntohs(vnet.u.vnet16[VNETID_SIZE16 - 1]));
device = dev;
}
csecurity = sxpr_child_value(exp, osecurity, intern("none"));
err = -ENOMEM;
goto exit;
}
+ vnet_peer_table->key_size = sizeof(struct VarpAddr);
vnet_peer_table->key_equal_fn = peer_key_equal_fn;
vnet_peer_table->key_hash_fn = peer_key_hash_fn;
vnet_peer_table->entry_free_fn = peer_entry_free_fn;
#----------------------------------------------------------------------------
-include $(XEN_ROOT)/tools/Rules.mk
+# Comment out when outside xen.
+#include $(XEN_ROOT)/tools/Rules.mk
VNETD_INSTALL_DIR = /usr/sbin
CPPFLAGS += -D __ARCH_I386_ATOMIC__
#----------------------------------------------------------------------------
+CFLAGS += -O3
CFLAGS += $(INCLUDES) $(LIBS)
LDFLAGS += $(LIBS)
if(err){
wprintf("> Unable to open tap device.\n"
"The tun module must be loaded and\n"
- "the vnet kernel module must not be loaded.");
+ "the vnet kernel module must not be loaded.\n");
deallocate(dev);
goto exit;
}
*
* @param vnetd vnetd
*/
-int vnetd_init(Vnetd *vnetd, int argc, char *argv[]){
+static int vnetd_init(Vnetd *vnetd, int argc, char *argv[]){
int err = 0;
// Use etherip-in-udp encapsulation.
return err;
}
-void vnet_select(Vnetd *vnetd, SelectSet *set){
+static void vnet_select(Vnetd *vnetd, SelectSet *set){
HashTable_for_decl(entry);
HashTable_for_each(entry, vnetd->vnet_table){
}
}
-void vnet_handle(Vnetd *vnetd, SelectSet *set){
+static void vnet_handle(Vnetd *vnetd, SelectSet *set){
HashTable_for_decl(entry);
HashTable_for_each(entry, vnetd->vnet_table){
}
}
-int vnetd_handle_udp(Vnetd *vnetd, struct sockaddr_in *addr, int sock){
+static int vnetd_handle_udp(Vnetd *vnetd, struct sockaddr_in *addr, int sock){
int err = 0, n = 0;
struct sockaddr_in peer, dest;
socklen_t peer_n = sizeof(peer), dest_n = sizeof(dest);
return err;
}
-int vnetd_handle_etherip(Vnetd *vnetd, struct sockaddr_in *addr, int sock){
+static int vnetd_handle_etherip(Vnetd *vnetd, struct sockaddr_in *addr, int sock){
int err = 0, n = 0;
struct sockaddr_in peer, dest;
socklen_t peer_n = sizeof(peer), dest_n = sizeof(dest);
Parser *parser;
} ConnClient;
-int conn_handle_fn(Conn *conn, int mode){
+static int conn_handle_fn(Conn *conn, int mode){
int err;
ConnClient *client = conn->data;
char data[1024] = {};
return (err < 0 ? err : 0);
}
-int vnetd_handle_unix(Vnetd *vnetd, int sock){
+static int vnetd_handle_unix(Vnetd *vnetd, int sock){
int err;
ConnClient *client = NULL;
Conn *conn = NULL;
struct sockaddr_un peer = {};
- int peer_n = sizeof(peer);
+ socklen_t peer_n = sizeof(peer);
int peersock;
peersock = accept(sock, (struct sockaddr *)&peer, &peer_n);
return err;
}
-void vnetd_select(Vnetd *vnetd, SelectSet *set){
+static void vnetd_select(Vnetd *vnetd, SelectSet *set){
SelectSet_add(set, vnetd->unix_sock, SELECT_READ);
SelectSet_add(set, vnetd->udp_sock, SELECT_READ);
SelectSet_add(set, vnetd->mcast_sock, SELECT_READ);
ConnList_select(vnetd->conns, set);
}
-void vnetd_handle(Vnetd *vnetd, SelectSet *set){
+static void vnetd_handle(Vnetd *vnetd, SelectSet *set){
if(SelectSet_in_read(set, vnetd->unix_sock)){
vnetd_handle_unix(vnetd, vnetd->unix_sock);
}
*/
static unsigned timer_alarms = 0;
-int vnetd_main(Vnetd *vnetd){
+static int vnetd_main(Vnetd *vnetd){
int err = 0;
SelectSet _set = {}, *set = &_set;
struct timeval _timeout = {}, *timeout = &_timeout;
return err;
}
-int getsockaddr(int sock, struct sockaddr_in *addr){
+static int getsockaddr(int sock, struct sockaddr_in *addr){
socklen_t addr_n = sizeof(struct sockaddr_in);
return getsockname(sock, (struct sockaddr*)addr, &addr_n);
}
-int vnetd_etherip_sock(Vnetd *vnetd){
+static int vnetd_etherip_sock(Vnetd *vnetd){
int err = 0;
if(!vnetd->etherip) goto exit;
return err;
}
-int vnetd_udp_sock(Vnetd *vnetd){
+static int vnetd_udp_sock(Vnetd *vnetd){
int err;
uint32_t mcaddr = vnetd_mcast_addr(vnetd);
return err;
}
-int vnetd_raw_sock(Vnetd *vnetd){
+static int vnetd_raw_sock(Vnetd *vnetd){
int err;
err = vnetd_raw_socket(vnetd, IPPROTO_RAW,
return err;
}
-int vnetd_unix_sock(Vnetd *vnetd){
+static int vnetd_unix_sock(Vnetd *vnetd){
int err = 0;
struct sockaddr_un addr = { .sun_family = AF_UNIX };
socklen_t addr_n;